--- id: TASK-017 title: Full team schedules status: "\U0001F3C1 Done" assignee: - '@humdrum-tiv' created_date: '2026-06-17 17:43' updated_date: '2026-06-18 01:17' labels: - feature dependencies: [] priority: medium ordinal: 17000 --- ## Description Show a team's complete season schedule (past results + upcoming fixtures) beyond the polled fetch window, via ESPN's team-schedule endpoint. Reachable from a team (e.g. from the detail view or a favorite). Generalizes TASK-009 (favorite last/next beyond window) — the schedule endpoint backs both. ## Acceptance Criteria - [x] #1 User can view a single team's full schedule (results + upcoming) - [x] #2 Data comes from the ESPN team-schedule endpoint, decoded in internal/espn into model types - [x] #3 Schedule entries show date, opponent, home/away, and result/score when played - [x] #4 Reachable from a team in the UI (detail view or favorites) ## Implementation Plan 1. model.TeamSchedule{Team,Season,Games []model.Game} (reuse Game). 2. espn.Client.TeamSchedule(ctx,l,teamID): GET teams/{id}/schedule; events[] like scoreboard BUT score is object {value,displayValue} -> schedule-specific competitor decode; reuse mapState/parseTime. Refactor mapTeam to share teamFromJSON. 3. UI viewSchedule: opened via g=away / G=home from a dashboard game card or detail view, and via enter on a standings row. Past results (score + W/L tint) + upcoming, scroll-clamped. esc returns to prior view. 4. Closes/supersedes TASK-009 (favorite last/next) via same endpoint. ## Final Summary Added a full team-schedule view (viewSchedule). What: - model.TeamSchedule{Team,Season,Games []model.Game} (reuses Game). - espn.Client.TeamSchedule fetches teams/{id}/schedule and maps events into model.Game. The schedule endpoint sends competitor score as an object {value,displayValue} (vs the scoreboard's bare string), so schedCompetitor/scoreObj decode separately; mapScheduleGame reuses mapState/parseTime and a new shared teamFromJSON helper (mapTeam refactored onto it). Games sorted chronologically. - UI: schedule.go renders past results (W/L/T + score, win-tinted) and upcoming fixtures (start time) with an 'upcoming' divider; opens scrolled to the next game. Reached three ways via openSchedule(): g/G (away/home, mirroring f/F favoriting) from a dashboard game card or the detail view, and enter on a standings row. prevMode records the opener so esc returns there; r refreshes. Supersedes TASK-009 (favorite last/next beyond the fetch window) — same endpoint. Tests: mapScheduleGame (object score, home/away, winner, state) and the no-competition (bye) skip. Live-smoke verified a 163-game MLB schedule maps with scores. go vet + go test ./... pass.